package com.ruoyi.web.controller.sincerity;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.SinDeed;
import com.ruoyi.system.domain.SinScore;
import com.ruoyi.system.domain.SinSincerity;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.domain.dto.StatisticsInfo;
import com.ruoyi.system.domain.dto.StatisticsParam;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author :
 * @date : 2023/4/2 23:13
 */
@Slf4j
@RestController
@RequestMapping("/sin/statistics")
public class SinStatisticsController extends BaseController {

    @Autowired
    private ISinDeedService deedService ;

    @Autowired
    private ISinSincerityService sinSincerityService;

    @Autowired
    private ISinScoreService scoreService ;

    @Autowired
    private ISysUserService userService ;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private SysUserRoleMapper urMapper ;


    public static final String STUDENT = "学生" ;
    public static final String TEACHER = "教师" ;

    @PostMapping("/getDeedStatistics")
    public AjaxResult getDeedStatistics(@RequestBody StatisticsParam param){
        HashMap<String, Object> map = new HashMap<>();
        List<SinDeed> list = deedService.selectSinDeedList(new SinDeed());
        List<SinDeed> parentList = list.stream().filter((d) -> (d.getParentId() == 0L)).collect(Collectors.toList());
        HashMap<String, Object> dataMap = new HashMap<>();
        HashMap<String, Integer> childMap = new HashMap<>();
        for (SinDeed sinDeed : list) {
            childMap.put(sinDeed.getName(),0) ;
        }
        for (SinDeed sinDeed : parentList) {
            dataMap.put(sinDeed.getName(),0) ;
        }
        LambdaQueryWrapper<SinSincerity> wrapper = new LambdaQueryWrapper<>();
        if (CollectionUtils.isNotEmpty(param.getTime())){
            wrapper.between(
                    SinSincerity::getCreateTime,
                    param.getTime().get(0),
                    param.getTime().get(1)) ;
        }
        SinSincerity sincerity = new SinSincerity();

        List<SysUser> users = new ArrayList<>() ;

        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        for (SysRole role : roles) {
            if (StringUtils.isNotBlank(role.getRoleName())) {
                if (STUDENT.equals(role.getRoleName())){
                    sincerity.setMainUserId(SecurityUtils.getUserId());
                }else if (TEACHER.equals(role.getRoleName())){
                    if (!SecurityUtils.isAdmin(SecurityUtils.getUserId())){
                        SysUser user = SecurityUtils.getLoginUser().getUser();
                        SysUser sysUser = new SysUser();
                        LambdaQueryWrapper<SysDept> wrapper1 = new LambdaQueryWrapper<>();
                        wrapper1.eq(SysDept::getLeader,user.getNickName()) ;
                        List<SysDept> list1 = this.deptService.list(wrapper1);
                        if (CollectionUtils.isNotEmpty(list1)){
                            for (SysDept sysDept : list1) {
                                sysUser.setDeptId(sysDept.getDeptId());
                                users.addAll(userService.selectUserList(sysUser)) ;
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(users)){
                        users = users.stream().distinct().sorted(Comparator.comparing(SysUser::getUserId)).collect(Collectors.toList()) ;
                    }
                }
            }
        }

        wrapper.eq(!Objects.isNull(sincerity.getMainUserId()),SinSincerity::getMainUserId,sincerity.getMainUserId()) ;

        wrapper.in(CollectionUtils.isNotEmpty(users),SinSincerity::getMainUserId, new ArrayList<>(users.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserId)).keySet())) ;


        List<SinSincerity> sinSincerities = sinSincerityService.list(wrapper);

        for (SinSincerity sinSincerity : sinSincerities) {
            if (childMap.containsKey(sinSincerity.getSincerityTypeName())) {
                childMap.put(sinSincerity.getSincerityTypeName(),childMap.get(sinSincerity.getSincerityTypeName()) + 1) ;
            }else {
                childMap.put(sinSincerity.getSincerityTypeName(),0) ;
            }
        }
        for (String string : childMap.keySet()) {
            for (SinDeed sinDeed : list) {
                if (sinDeed.getName().equals(string)) {
                    Long parentId = sinDeed.getParentId();
                    for (SinDeed deed : list) {
                        if (deed.getId().equals(parentId)) {
                            dataMap.put(deed.getName(),Integer.parseInt(dataMap.get(deed.getName()).toString()) + Integer.parseInt(childMap.get(string).toString())) ;
                        }
                    }
                }
            }
        }
        HashMap<String, String> hashMap = new HashMap<>();
        List<SinScore> scores = scoreService.list();
        List<String> collect = new ArrayList<>() ;
        if (CollectionUtils.isNotEmpty(scores)){
            Set<String> strings = scores.stream().collect(Collectors.toMap(SinScore::getName, SinScore::getId)).keySet();
            collect = new ArrayList<>(strings);
            for (String s : collect) {
                hashMap.put(s,"0") ;
            }
        }
        List<SysUser> sysUsers = new ArrayList<>() ;
        if (CollectionUtils.isNotEmpty(users)){
            sysUsers = users ;
        }else {
            sysUsers = userService.selectUserList(new SysUser());
        }
        if (!Objects.isNull(sincerity.getMainUserId())){
            sysUsers.clear();
            SysUser user = userService.selectUserById(sincerity.getMainUserId());
            sysUsers.add(user) ;

        }
        List<SysUserRole> userRoles = urMapper.selectList(new LambdaQueryWrapper<>());
        List<Long> studentUserIdList = userRoles.stream().filter((u) -> (u.getRoleId().equals(2L))).collect(Collectors.toMap(SysUserRole::getUserId, SysUserRole::getUserId)).keySet().stream().collect(Collectors.toList());
        /**获取所有的诚信事迹*/
        List<SinSincerity> sincerities = sinSincerityService.selectSinSincerityList(new SinSincerity());

        List<SinDeed> deeds = deedService.selectSinDeedList(new SinDeed());
        Map<Long, SinDeed> scoreMap = deeds.stream().collect(Collectors.toMap(SinDeed::getId, (a) -> (a)));
        Map<Long, SinDeed> parentMap = deeds.stream().filter((d) -> (d.getParentId() == 0L)).collect(Collectors.toMap(SinDeed::getId, (d) -> (d)));

        List<SysUser> userList = sysUsers.stream().filter((u)->(studentUserIdList.contains(u.getUserId()))).distinct().collect(Collectors.toList());
        for (SysUser user : userList) {
            user.setScoreNumber(80.0);
        }
        for (SysUser sysUser : userList) {
            for (SinSincerity sincerityInfo : sincerities) {
                if (sincerityInfo.getMainUserId().equals(sysUser.getUserId())){
                    sysUser.setScoreNumber(new BigDecimal(sysUser.getScoreNumber())
                            .add(
                                    new BigDecimal(scoreMap.get(sincerityInfo.getSincerityTypeId()).getScoreNumber())
                                            .multiply(
                                                    new BigDecimal(
                                                            parentMap.get(
                                                                    scoreMap.get(sincerityInfo.getSincerityTypeId()).getParentId())
                                                                    .getNumberScale()
                                                    ))
                            ).setScale(2,BigDecimal.ROUND_HALF_UP)
                            .doubleValue());
                }
            }
        }


        for (String s : collect) {
            hashMap.put(s,userList.stream().filter((u)->{
                for (SinScore score : scores) {
                    if (s.equals(score.getName())){
                        System.out.println("分数:" + u.getScoreNumber());
                        if (Objects.isNull(score.getMinScore()) && !Objects.isNull(score.getMaxScore())){
                            return u.getScoreNumber() < Double.valueOf(score.getMaxScore());
                        }else if (!Objects.isNull(score.getMinScore()) && Objects.isNull(score.getMaxScore())){
                            return u.getScoreNumber() > Double.valueOf(score.getMinScore());
                        }else if (!Objects.isNull(score.getMinScore()) && !Objects.isNull(score.getMaxScore())){
                            return u.getScoreNumber() >= Double.valueOf(score.getMinScore()) && u.getScoreNumber() < Double.valueOf(score.getMaxScore());
                        }else {
                            return false ;
                        }
                    }
                }
                return false ;
            }).count() + "") ;
        }
        ArrayList<StatisticsInfo> infos = new ArrayList<>();
        for (String s : collect) {
            StatisticsInfo info = new StatisticsInfo();
            for (SinScore score : scores) {
                if (s.equals(score.getName())){
                    info.setName(s + "--[" +
                            (Objects.isNull(score.getMinScore()) ? "0" : score.getMinScore())
                            +"," +
                            (Objects.isNull(score.getMaxScore()) ? "~" : score.getMaxScore())
                            + "]" );

                }
            }
            info.setValue(hashMap.get(s));
            infos.add(info) ;
        }

        if (sysUsers.size() == 1){
            map.put("studentScore",sysUsers.get(0).getScoreNumber());
        }


        map.put("title",dataMap.keySet().toArray()) ;
        map.put("titleInfo",dataMap.values().toArray()) ;
        map.put("sincerityDataList",infos) ;
        return success(map) ;
    }
}
